package hc.bre

import static org.assertj.core.api.InstanceOfAssertFactories.MAP
import static org.junit.jupiter.api.Assertions.*

import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

import hc.Util
import hc.bre.func.FunctionDefinition
import hc.bre.rest.manage.MainService
import hc.bre.script.ClosureDefinition

@groovy.transform.CompileStatic
//@SpringBootTest
class ScriptBlockAndFunctionTest {
	@Autowired
	MainService mainService;
	String closureString='''
{
    "imports": [
        {
			"id":1,
            "code": "java.lang.Math",
            "markAll": true,
            "markStatic": true
        }
    ],
    "rname": "SumTo4",
    "rversion": 16,
    "script": "def add={x,y->return x + y}\\n\\nreturn add(1,add(2,add(3,Math.abs(-4))))",
    "rmemo": "",
    "rpath": "xsxdjc/script/SumTo4",
    "rid": 86,
    "rtype": "rule:script",
    "rtdata": ""
}
'''
	@Test
	void closureCreate()
	{
		def ruleDef = new ClosureDefinition()
		assert ruleDef.rtype =='rule:script';
	}

	@Test
	void closureLoad() {
		Map map = (Map)Util.jsonRead(closureString)
		ClosureDefinition ruleDef = new ClosureDefinition().load(map);
//		assert ruleDef.rid == 86
		assert ruleDef.imports.size() ==1
		assert ruleDef.rtype =='rule:script'
	}

	@Test
	void closureBuildAndEvalute() {
		Map map = (Map)Util.jsonRead(closureString)
		ClosureDefinition ruleDef = new ClosureDefinition().load(map);
		
		String script = ruleDef.buildRuleScript();
		println script;
		
		def binding = ruleDef.buildRuleEvaluate([:],null)
		assert binding['result']['ret'] == 10
	}
	
	@Test
	void closureBuildAndEvaluteOfImport() {
		String closureString ='''
{
  "rid": 112,
  "rtype": "rule:script",
  "rname": "MaxOfList",
  "rpath": "xsxdjc/script/MaxOfList",
  "rversion": 13,
  "rtdata": "",
  "rmemo": "",
  "rtest": "{}",
  "rmaxid": 1,
  "script": "if(list)\\n{\\n\\tdef max = list[0]\\n\\tlist.forEach({max = it>max?it:max})\\n\\t\\n\\treturn max\\n}\\nelse{\\n    return null\\n    \\n};",
  "imports": [{"id":1,
            "code": "java.lang.Math",
            "markAll": true,
            "markStatic": true
			}
			]
}
'''
		Map map = (Map)Util.jsonRead(closureString)
		ClosureDefinition ruleDef = new ClosureDefinition().load(map);
		
		def binding = ruleDef.buildRuleEvaluate([list:[1,3,8,3,4,5,7,1]],null)
		
		assert binding['result']['ret'] == 8
	}

	@Test
	void functionCreate() {
		def ruleDef = new FunctionDefinition()
		assert ruleDef.rtype =='function';
	}
	
	@Test
	void functionLoad() {
		Map map = (Map)Util.jsonRead(funString)
		FunctionDefinition ruleDef = new FunctionDefinition().load(map);

//		assert ruleDef.rid == 87
		assert ruleDef.imports.size() ==1
		assert ruleDef.list.size() ==1
		assert ruleDef.list.args.size() ==1
	}

	@Test
	void functionBuildAndEvaluate()
	{
		Map map = (Map)Util.jsonRead(funString)
		FunctionDefinition ruleDef = new FunctionDefinition().load(map);
		def binding = ruleDef.buildRuleEvaluate([_func_:'fabonici',num:10],null)
		//,"result = xsxdjc.script.Fun.fabonici(10)"
		assert binding['result'] == 55
	}

	static List getenv()
	{
		def envm = System.getenv();
		List lst =[]
		envm.forEach({k,v ->
			lst.add("${k}=${v}")
		})
		return lst;
	}


	String funString=
	"""
{
    "rid": 87,
    "rname": "用户定义函数",
    "rtype": "function",
    "rpath": "xsxdjc/script/Fun",
    "rtdata": "",
    "rversion": 0,
    "rmemo": "",
	"rmaxid": 1,
    "imports": [
        {
            "id":1,
            "code": "java.lang.Math",
            "markAll": true,
            "markStatic": true
        }
    ],
    "list": [
        {
            "id": 1,
            "code": "fabonici",
            "name": "斐波那契函数",
            "args": [
                {
                    "id": 0,
                    "code": "num",
                    "name": "",
                    "type": "any"
                }
            ],
            "script": "if(num<3) return 1;\\nreturn fabonici(num-2) + fabonici(num-1)",
            "editable": false
        }
    ]
}
"""
}
